package com.zang.jdk8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class CompletableFutureDemo {

    public static Integer calc(Integer para) {
        try {
            //长时间的计算
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.getMessage();
        }
        return para * para;
    }
    static Integer js(Integer para){
        return para + para;
    }

    public void test1(){
        long start = System.currentTimeMillis();
        // 结果集
        List<String> list = new ArrayList<>();

        List<Integer> taskList = Arrays.asList(2, 1, 3, 4, 5, 6, 7, 8, 9, 10);
        // 全流式处理转换成CompletableFuture[]+组装成一个无返回值CompletableFuture，join等待执行完毕。返回结果whenComplete获取
        CompletableFuture[] cfs = taskList.stream()
                .map(integer -> CompletableFuture.supplyAsync(() -> calc(integer))
                        .thenApply(h-> Integer.toString(h))
                        .whenComplete((s, e) -> {
                            System.out.println("任务"+s+"完成!result="+s+"，异常 e="+e+","+new Date());
                            list.add(s);
                        })
                ).toArray(CompletableFuture[]::new);
        // 封装后无返回值，必须自己whenComplete()获取
        CompletableFuture.allOf(cfs).join();
        System.out.println("list="+list+",耗时="+(System.currentTimeMillis()-start));
    }


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Void> future2 = CompletableFuture
                .supplyAsync(() -> js(100))
                .thenCompose((param2)-> CompletableFuture.supplyAsync(() -> js(param2 + 20)))
                .thenAccept(System.out::println);
        future2.join();

    }

    //所有的线程都是Deamo线程,如果主线程退出,所有的都会退出
    static void testDemo() throws ExecutionException, InterruptedException {
        CompletableFuture<Void> future = CompletableFuture
                //开启一个线程,默认的执行任务
                .supplyAsync(() -> calc(50))
                //将上一个的执行结果进行处理
                .thenApply((i) -> Integer.toString(i))
                .thenApply((s -> "\"" + s + "\""))
                .thenAccept(System.out::println);

        CompletableFuture<Void> future1 = CompletableFuture
                //相当于runnable,底层是通过Excutor实现,启动start
                .supplyAsync(() -> calc(50))
                //将执行结果传递给下一个future
                .thenCompose((i) -> CompletableFuture.supplyAsync(() -> calc(i)))
                //执行最终的处理结果
                .thenApply((s -> "\"" + s + "\""))
                .thenAccept(System.out::println);

        //获取结果
        future.get();
        future1.get();
    }




}